package anc.tankshooter.network.ui;

import java.util.ArrayList;

import org.andengine.entity.primitive.Rectangle;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.sprite.TiledSprite;
import org.andengine.entity.text.Text;
import org.andengine.input.touch.TouchEvent;
import org.andengine.util.color.Color;

import anc.server.tankshooter.models.Account;
import anc.server.tankshooter.models.Match;
import anc.tankshooter.GameActivity;
import anc.tankshooter.GameSetting;
import anc.tankshooter.network.CommandList;
import anc.tankshooter.network.GameClient;
import anc.tankshooter.network.GameDataListener;
import anc.tankshooter.ui.IScreen;
import anc.tankshooter.ui.MainMenuScreen;
import anc.tankshooter.ui.ResourcesManager;
import anc.tankshooter.ui.SceneManager;
import anc.tankshooter.ui.SceneManager.SceneType;
import anc.tankshooter.ui.SettingScreen;

/**
 * Hiển thị danh sách các bàn chơi. Mặc định là 9 bàn chơi.<br>
 * Số lượng bàn chơi có thể thay đổi bỏi SERVER. Sau khi login thành công<br>
 * client sẽ gửi thông điệp lấy tất cả các bàn chơi hiện có và trạng thái từng bàn chơi.
 * @author tauitdnmd
 *
 */
public class MatchListScreen extends IScreen {
	
	private LoginScreen mLoginScreen;
	private SignUpScreen mSignUpScreen;
	private Sprite mBackground;
	private Rectangle mRectBox,mBackgroundBox;	
	private ArrayList<Text> mHeaderTexts;
	private ArrayList<Sprite> mIndexRooms,mMapPreviews;
	private ArrayList<Text> mOwners;
	private ArrayList<Text> mCompetitors;
	private ArrayList<Text> mActions;
	private Text mMessageText,mAccountInfoText;
	
	private TiledSprite mBtnSignIn,mBtnSignUp;
	private TiledSprite mBtnRefesh,mBtnStart,mBtnLeave;
	
	private Text mJoinedRoomText;
	
	private boolean mIsSending;
	private ArrayList<Match> mRoomMatchs;
	private int mSelectedRoom,mSelectedMap, counter;
	
	public MatchListScreen() {
		
		attachChild(mBackground);
		attachChild(mRectBox);
		attachChild(mBackgroundBox);
		
		attachChild(mBtnSignUp);  registerTouchArea(mBtnSignUp);
		attachChild(mBtnSignIn); registerTouchArea(mBtnSignIn);
		
		attachChild(mMessageText);
		attachChild(mAccountInfoText);
		attachChild(mJoinedRoomText);
		
		for(Sprite sp: mMapPreviews){
			attachChild(sp);
		}
		
		for(Text t	: mHeaderTexts){
			attachChild(t);
		}
		
		for(Sprite sp: mIndexRooms){
			attachChild(sp);
		}
		for(Text t: mOwners){
			attachChild(t);
		}
		
		for(Text t: mCompetitors){
			attachChild(t);
		}

		for(Text t: mActions){
			registerTouchArea(t);
			attachChild(t);
		}

		attachChild(mBtnRefesh); registerTouchArea(mBtnRefesh);
		attachChild(mBtnStart); registerTouchArea(mBtnStart);
		attachChild(mBtnLeave); registerTouchArea(mBtnLeave);
		this.setBackgroundEnabled(false);
		
		mRoomMatchs = new ArrayList<Match>();
		registerDataListener();
	}
	
	@Override
	protected void createScene() {
		mSelectedRoom = -1;
		mSelectedMap = 1;
		mMapPreviews = new ArrayList<Sprite>();
		mHeaderTexts = new ArrayList<Text>();
		mIndexRooms = new ArrayList<Sprite>();
		mOwners = new ArrayList<Text>();
		mCompetitors = new ArrayList<Text>();
		mActions = new ArrayList<Text>();
		
		mLoginScreen = new LoginScreen(new SettingScreen.SettingButtonListener() {
			
			@Override
			public void onOkClicked() {				
			}
			
			@Override
			public void onCancleClicked() {
				clearChildScene();
			}
		});
		
		mSignUpScreen = new SignUpScreen(new SettingScreen.SettingButtonListener() {
			
			@Override
			public void onOkClicked() {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onCancleClicked() {
				clearChildScene();
			}
		});
		
		float x = 50;
		float y = GameActivity.CAMERA_HEIGHT/2 - 400/2;
		
		mBtnSignUp = new TiledSprite(x, y-ResourcesManager.getInstance().mBtnTexture.getHeight()-3,ResourcesManager.getInstance().mBtnTexture, mVertextManager){
			@Override
			public boolean onAreaTouched(TouchEvent event,float tx, float ty) {
				
				if(event.getAction()==TouchEvent.ACTION_OUTSIDE||
						event.getAction()==TouchEvent.ACTION_CANCEL){
					mBtnSignUp.setCurrentTileIndex(26);
				}else if(event.getAction()==TouchEvent.ACTION_UP){
					mBtnSignUp.setCurrentTileIndex(26);
					setChildScene(mSignUpScreen);
				}else if(event.getAction()==TouchEvent.ACTION_DOWN) {
					mBtnSignUp.setCurrentTileIndex(27);
				}
				return super.onAreaTouched(event, tx, ty);
			}
		};
		mBtnSignUp.setCurrentTileIndex(26);
		
		mBtnSignIn = new TiledSprite(x + ResourcesManager.getInstance().mBtnTexture.getWidth()+10, y-ResourcesManager.getInstance().mBtnTexture.getHeight()-3,ResourcesManager.getInstance().mBtnTexture, mVertextManager){
			@Override
			public boolean onAreaTouched(TouchEvent event,float tx, float ty) {
				
				if(event.getAction()==TouchEvent.ACTION_OUTSIDE||
						event.getAction()==TouchEvent.ACTION_CANCEL){
					if(mBtnSignIn.getCurrentTileIndex()==24||mBtnSignIn.getCurrentTileIndex()==25)
						mBtnSignIn.setCurrentTileIndex(24);
					if(mBtnSignIn.getCurrentTileIndex()==28||mBtnSignIn.getCurrentTileIndex()==29)
						mBtnSignIn.setCurrentTileIndex(28);
				}else if(event.getAction()==TouchEvent.ACTION_UP){
					if(mBtnSignIn.getCurrentTileIndex()==24||mBtnSignIn.getCurrentTileIndex()==25)
						mBtnSignIn.setCurrentTileIndex(24);
					if(mBtnSignIn.getCurrentTileIndex()==28||mBtnSignIn.getCurrentTileIndex()==29)
						mBtnSignIn.setCurrentTileIndex(28);
					
					if(GameActivity.mClient.isConnected()) {
						if((mBtnSignIn.getCurrentTileIndex()==24||mBtnSignIn.getCurrentTileIndex()==25)){
							setChildScene(mLoginScreen,false,false,true);
						}else if(mBtnSignIn.getCurrentTileIndex()==28||mBtnSignIn.getCurrentTileIndex()==29){
							GameActivity.mClient.setAccount(null);
							GameActivity.mClient.stopClient();
							GameActivity.mClient=new GameClient();
							registerDataListener();
							GameActivity.mClient.startClient();
							mBtnSignIn.setCurrentTileIndex(24);
						}
					}
				}else if(event.getAction()==TouchEvent.ACTION_DOWN) {
					if(mBtnSignIn.getCurrentTileIndex()==24||mBtnSignIn.getCurrentTileIndex()==25)
						mBtnSignIn.setCurrentTileIndex(25);
					if(mBtnSignIn.getCurrentTileIndex()==28||mBtnSignIn.getCurrentTileIndex()==29)
						mBtnSignIn.setCurrentTileIndex(29);
				}
				return super.onAreaTouched(event, tx, ty);
			}
		};
		mBtnSignIn.setCurrentTileIndex(24);
		
		mBackground = new Sprite(0,0,ResourcesManager.getInstance().mBackgroundTexture,  ResourcesManager.getInstance().mVertexManager);
		
		
		mRectBox = new Rectangle(x, y, 400, 400, mVertextManager);
		
		mRectBox.setColor(Color.BLACK); mRectBox.setAlpha(0.6f);
		
		mMessageText = new Text(x+10, y+350, ResourcesManager.getInstance().mWhiteFont15,"",256,
				   ResourcesManager.getInstance().mVertexManager);
		mAccountInfoText = new Text(x+10, y, ResourcesManager.getInstance().mWhiteFont15,"",256,
				   ResourcesManager.getInstance().mVertexManager);
		mJoinedRoomText = new Text(x+420, y+20, ResourcesManager.getInstance().mWhiteFont15,"",256,
				   ResourcesManager.getInstance().mVertexManager);
		
		mBackgroundBox = new Rectangle(x+410, y, 290, 400, mVertextManager);
		mBackgroundBox.setColor(Color.BLACK); mBackgroundBox.setAlpha(0.6f);
		
		mBtnRefesh = new TiledSprite(GameActivity.CAMERA_WITDH/2-40, y+400-50,ResourcesManager.getInstance().mBtnTexture, mVertextManager){
			@Override
			public boolean onAreaTouched(TouchEvent event,float tx, float ty) {
				
				if(event.getAction()==TouchEvent.ACTION_OUTSIDE||
						event.getAction()==TouchEvent.ACTION_CANCEL){
					mBtnRefesh.setCurrentTileIndex(20);
				}else if(event.getAction()==TouchEvent.ACTION_UP){
					mBtnRefesh.setCurrentTileIndex(20);
					doRefeshRoomListClick();
				}else if(event.getAction()==TouchEvent.ACTION_DOWN) {
					mBtnRefesh.setCurrentTileIndex(21);
				}
				return super.onAreaTouched(event, tx, ty);
			}
		};
		mBtnRefesh.setCurrentTileIndex(20);
		
		mBtnStart = new TiledSprite(x+550, y+400-50,ResourcesManager.getInstance().mBtnTexture, mVertextManager){
			@Override
			public boolean onAreaTouched(TouchEvent event,float tx, float ty) {
				
				if(event.getAction()==TouchEvent.ACTION_OUTSIDE||
						event.getAction()==TouchEvent.ACTION_CANCEL){
					mBtnStart.setCurrentTileIndex(22);
				}else if(event.getAction()==TouchEvent.ACTION_UP){
					mBtnStart.setCurrentTileIndex(22);
					doStartClick();
				}else if(event.getAction()==TouchEvent.ACTION_DOWN) {
					mBtnStart.setCurrentTileIndex(23);
				}
				return super.onAreaTouched(event, tx, ty);
			}
		};
		mBtnStart.setCurrentTileIndex(22);
		
		mBtnLeave = new TiledSprite(x+450, y+400-50,ResourcesManager.getInstance().mBtnTexture, mVertextManager){
			@Override
			public boolean onAreaTouched(TouchEvent event,float tx, float ty) {
				
				if(event.getAction()==TouchEvent.ACTION_OUTSIDE||
						event.getAction()==TouchEvent.ACTION_CANCEL){
					mBtnLeave.setCurrentTileIndex(18);
				}else if(event.getAction()==TouchEvent.ACTION_UP){
					mBtnLeave.setCurrentTileIndex(18);
					doLeaveClick();
				}else if(event.getAction()==TouchEvent.ACTION_DOWN) {
					mBtnLeave.setCurrentTileIndex(19);
				}
				return super.onAreaTouched(event, tx, ty);
			}
		};
		mBtnLeave.setCurrentTileIndex(18);
		
		int padding = 25;
		y+=50;
		int i=-1;
		Text nameText = new Text(x+50, y+50+i*padding,ResourcesManager.getInstance().mWhiteFont18,
				"P1", mVertextManager);
		
		Text name2Text = new Text(x+50+110, y+50+i*padding,ResourcesManager.getInstance().mWhiteFont18,
				"P2", mVertextManager);
		
		Text normalText = new Text(x+50+230, y+50+i*padding,ResourcesManager.getInstance().mWhiteFont18,
				"Action", mVertextManager);
		
		mHeaderTexts.add(nameText);
		mHeaderTexts.add(name2Text);
		mHeaderTexts.add(normalText);
		
		for(i=0;i<9;i++){
			TiledSprite sp = new TiledSprite(x+20, y+50+i*padding, ResourcesManager.getInstance().mNumbersTexture,mVertextManager);
			sp.setCurrentTileIndex(i); sp.setSize(20,20);
			
			
			Text name1Text = new Text(x+50, y+50+i*padding,ResourcesManager.getInstance().mWhiteFont20,
							"",10, mVertextManager);
			
			
			Text levelText = new Text(x+50+120, y+50+i*padding,ResourcesManager.getInstance().mWhiteFont20,
					"",10, mVertextManager);
			
			
			Text actionText = new Text(x+50+230, y+50+i*padding,ResourcesManager.getInstance().mWhiteFont20,
					"",8, mVertextManager){
				@Override
				public boolean onAreaTouched(TouchEvent event,float tx, float ty) {
					
					if(event.getAction()==TouchEvent.ACTION_UP) {
						int roomIndex = this.getTag();
						if(roomIndex>=0&& roomIndex<mRoomMatchs.size()){
							Match m = mRoomMatchs.get(roomIndex);
							doJoinRoomClick(this.getTag());
						}
					}
					return super.onAreaTouched(event, tx, ty);
				}
			};
			actionText.setTag(i);
			
			mIndexRooms.add(sp);
			mOwners.add(name1Text);
			mCompetitors.add(levelText);
			mActions.add(actionText);
			
			name1Text.setAlpha(0.5f); levelText.setAlpha(0.5f);
			actionText.setAlpha(0.5f);
		}
		
		for(i=0;i<GameSetting.MAX_LEVEL;i++){
			TiledSprite sp = new TiledSprite(x+440, y+40+80*i+10*i, ResourcesManager.getInstance().mMapPreviewTexture, ResourcesManager.getInstance().mVertexManager){
				@Override
				public boolean onAreaTouched(TouchEvent event,float tx, float ty) {
					if(event.getAction()==TouchEvent.ACTION_DOWN) {
						this.setAlpha(0.5f);
					}else this.setAlpha(1f);
					if(event.getAction()==TouchEvent.ACTION_UP) {
						if(mSelectedRoom>=0){
							Match m = mRoomMatchs.get(mSelectedRoom);
							if(GameActivity.mClient.getAccount().getAccountId()==m.getOwnerId())
								mSelectedMap= this.getTag()+1;
						}
					}
					
					return super.onAreaTouched(event, tx, ty);
				}
			};
			sp.setSize(220,80);
			sp.setCurrentTileIndex(i);
			sp.setTag(i);
			registerTouchArea(sp);
			mMapPreviews.add(sp);
		}
		
	}

	

	private void registerDataListener() {
		
		GameActivity.mClient.setPacketReceiver(new GameDataListener() {
			
			
			@Override
			public void onConnected() {
				mAccountInfoText.setText("Network: Connected");
			}
			@Override
			public void onDisconnected() {
				mAccountInfoText.setText("Network: Disconnected");
				mBtnSignIn.setCurrentTileIndex(24);
				GameActivity.mClient.setAccount(null);
			}
			
			@Override
			public void onSignupResult(boolean isSuccess) {
				clearChildScene();
				mMessageText.setText(isSuccess?"Successed!":"Failed!");
			}
			@Override
			public void onLoginSuccessed(Account acc) {
				acc.setUsername(LoginScreen.mUser);
				acc.setPassword(LoginScreen.mPass);
				clearChildScene();
				GameActivity.mClient.setAccount(acc);
				doRefeshRoomListClick();
				mAccountInfoText.setText("Network: Connected\n"+"User:"+acc.getUsername()+"\nName:"+acc.getName());
				mBtnSignIn.setCurrentTileIndex(28);
			}

			@Override
			public void onLoginFailed(int errorCode) {
				mMessageText.setText(errorCode==CommandList.SERVER_LOGIN_FAILED_SIGNED?"You have already signed in!":"Login failed!");
				clearChildScene();
			}
			
			@Override
			public void onReceiveRoomList(ArrayList<Match> ml) {
				counter++;
				mRoomMatchs.clear();
				for(int i=0;i<9;i++){
					mOwners.get(i).setText("---"); mOwners.get(i).setAlpha(0.5f);
					mCompetitors.get(i).setText("---"); mCompetitors.get(i).setAlpha(0.5f);
					mActions.get(i).setText("Join"); mActions.get(i).setAlpha(0.5f);
				}
				for(int i = 0;i<ml.size();i++){
					Match m = ml.get(i);
					mRoomMatchs.add(m);
					mOwners.get(i).setText( m.getOwnerId()<0?"---": m.getOwner());
					mCompetitors.get(i).setText(m.getCompetitorId()<0?"---": m.getCompetitor());
					if(m.getOwnerId()==-1||m.getCompetitorId()==-1){
						mActions.get(i).setText("Join");
					}
					else mActions.get(i).setText("Waiting");
					int accountId = GameActivity.mClient.getAccount().getAccountId();
					if(m.getOwnerId()==accountId||m.getCompetitorId()==accountId) {
						mSelectedRoom = i;
						mSelectedMap = m.getMapId();
					}
					mOwners.get(i).setAlpha(1f);
					mCompetitors.get(i).setAlpha(1f);
					mActions.get(i).setAlpha(1f);
				}
			}

			@Override
			public void onNewPlayerJoin(int room,Match m) {
				counter++;
				mRoomMatchs.remove(room); mRoomMatchs.add(room, m);
				
				mOwners.get(room).setText( m.getOwnerId()<0?"---": m.getOwner());
				mCompetitors.get(room).setText(m.getCompetitorId()<0?"---": m.getCompetitor());
				if(m.getOwnerId()==-1||m.getCompetitorId()==-1){
					mActions.get(room).setText("Join");
				} else mActions.get(room).setText("Waiting"); 
				int accountId = GameActivity.mClient.getAccount().getAccountId();
				if(m.getOwnerId()==accountId||m.getCompetitorId()==accountId) {
					mSelectedRoom = room;
					mSelectedMap = m.getMapId();
				}
				
				mOwners.get(room).setAlpha(1f);
				mCompetitors.get(room).setAlpha(1f);
				mActions.get(room).setAlpha(1f);
			}
			
			@Override
			public void onJoinFaild(int room) {
				mMessageText.setText("You can't join :Room = "+room);
			}
			@Override
			public void onLeaveRoom(int accountId) {
				if(accountId == GameActivity.mClient.getAccount().getAccountId()){
					mSelectedRoom = -1;
					mSelectedMap = 1;
				}
			}
			@Override
			public void onStartGame(int map) {
				if(mSelectedRoom>=0 && mSelectedRoom < mRoomMatchs.size()) {
					if(GameActivity.mClient.send(CommandList.CLIENT_STARTED, null)){
						Match m = mRoomMatchs.get(mSelectedRoom);
						m.setMapId(map);
						ResourcesManager.getInstance().loadGameResources();
						NetworkGameScreen sc = new NetworkGameScreen(m);
						SceneManager.getInstance().setScene(sc);
					}
				}
			}
			@Override
			public void onServerDisconnected() {
				
			}
		});
	}

	@Override
	public void onUpdateScreen(float second) {
		
		mAccountInfoText.setText(GameActivity.mClient.isConnected() ?"Network: Connected":"Network: Disconnected");
		if(GameActivity.mClient.isConnected()&& GameActivity.mClient.isLogin()){
			mBtnSignIn.setCurrentTileIndex(28);
			Account acc = GameActivity.mClient.getAccount();
			mAccountInfoText.setText("Network: Connected\n"+"User:"+acc.getUsername()+"\nName:"+acc.getName());
			if(mRoomMatchs.size()<=0){
				doRefeshRoomListClick();
			}
		}else {
			mSelectedMap =-1;
			mSelectedRoom = -1;
			mRoomMatchs.clear();
			for(int i=0;i<9;i++){
				mOwners.get(i).setText("---"); mOwners.get(i).setAlpha(0.5f);
				mCompetitors.get(i).setText("---"); mCompetitors.get(i).setAlpha(0.5f);
				mActions.get(i).setText("Join"); mActions.get(i).setAlpha(0.5f);
			}
		}
		
		
		if(mSelectedRoom >=0 && mSelectedRoom<mRoomMatchs.size()){
			Match m = mRoomMatchs.get(mSelectedRoom);
			mBtnLeave.setVisible(true);
			mBtnStart.setVisible(m.getOwnerId()>=0&&m.getCompetitorId()>=0 && GameActivity.mClient.getAccount().getAccountId()==m.getOwnerId());
			for(Sprite s : mMapPreviews){
				s.setVisible(true);
			}
			
			String info = String.format("Room: %d - Map: %d\nOwner: %s\nCompetitor: %s\nStatus: %s",
										mSelectedRoom,mSelectedMap,
										m.getOwner(),m.getCompetitor(),m.getOwnerId()>=0&&m.getCompetitorId()>=0?"READY":"WAITING...");
			mJoinedRoomText.setText(info);
		}else{
			mBtnLeave.setVisible(false);
			mBtnStart.setVisible(false);
			for(Sprite s : mMapPreviews){
				s.setVisible(false);
			}
			mJoinedRoomText.setText("JOIN A ROOM TO START !");
		}
	}

	@Override
	public boolean onBackKeyPressed() {
		GameActivity.mClient.setPacketReceiver(null);
		ResourcesManager.getInstance().loadMenuResources();
		MainMenuScreen screen = new MainMenuScreen();
		SceneManager.getInstance().setScene(screen);
		return true;
	}

	@Override
	public SceneType getSceneType() {
		return null;
	}

	@Override
	public void disposeScene() {
		
	}

	private void doRefeshRoomListClick(){
		if(!mIsSending) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					
					synchronized(GameActivity.mClient){
						mIsSending = true;
						if(!GameActivity.mClient.sendGetAllRoom())
							mMessageText.setText("The request wasnt sent!");
						mIsSending = false;
					}
					
				}
			}).start();
		}
	}
	
	private void doJoinRoomClick(final int room){
		
		if(!mIsSending && mSelectedRoom < 0 && mSelectedRoom < mRoomMatchs.size()) {
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					mIsSending = true;
					synchronized(GameActivity.mClient){
						if(!GameActivity.mClient.sendJoinRoom(room))
							mMessageText.setText("The request wasnt sent!");
					}
					mIsSending = false;
				}
			}).start();
		}
		if(mSelectedRoom>=0){
			mMessageText.setText("You can't join this room:"+ room+"\n"+"You already joined other room: "+mSelectedRoom);
		}
	}
	
	private void doLeaveClick() {
		if(!mIsSending && mSelectedRoom>=0 && mSelectedRoom < mRoomMatchs.size() ) {
			Match m = mRoomMatchs.get(mSelectedRoom);
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					mIsSending = true;
					synchronized(GameActivity.mClient){
						if(!GameActivity.mClient.sendLeaveRoom()){
							 mMessageText.setText("The request wasnt sent!");
						}
					}
					mIsSending = false;
				}
			}).start();
		}
		if(mSelectedRoom<0)
			 mMessageText.setText("Please join a room first!");
	}
	
	private void doStartClick(){
		
		
		if(!mIsSending && mSelectedRoom>=0 &&  mSelectedRoom < mRoomMatchs.size()) {
			Match m = mRoomMatchs.get(mSelectedRoom);
			if(m.getOwnerId()==GameActivity.mClient.getAccount().getAccountId()) {
				new Thread(new Runnable() {
					
					@Override
					public void run() {
						mIsSending = true;
						synchronized(GameActivity.mClient){
							GameActivity.mClient.sendStartGame(mSelectedMap);
						}
						
						mIsSending = false;
					}
				}).start();
			}else mMessageText.setText("You're not owner of this room :"+mSelectedRoom);
		}
		
		if(mSelectedRoom<0)
			 mMessageText.setText("Please join a room first!");
	}
	
	
}
